package com.heima.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.search.pojos.ApAssociateWords;
import com.heima.search.mapper.ApAssociateWordsMapper;
import com.heima.search.model.Trie;
import com.heima.search.service.ApAssociateWordsService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class ApAssociateWordsServiceImpl extends ServiceImpl<ApAssociateWordsMapper, ApAssociateWords> implements ApAssociateWordsService {
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Override
    public ResponseResult searchV2(UserSearchDto userSearchDto) {
        // 1. 检查参数 (关键词)
        if(userSearchDto == null || StringUtils.isBlank(userSearchDto.getSearchWords())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        // 2. 去redis中查询缓存的联想词汇表
        String associate_list = stringRedisTemplate.opsForValue().get("associate_list");
        List<ApAssociateWords> apAssociateWords = null;
        if(StringUtils.isNotBlank(associate_list)){
            apAssociateWords = JSONArray.parseArray(associate_list, ApAssociateWords.class);
        }
        // 3. 没有查询到，就去数据库中查询词汇表, 缓存到redis中
        if(apAssociateWords == null){
            apAssociateWords = this.list();
            if(apAssociateWords!= null && !apAssociateWords.isEmpty()){
                stringRedisTemplate.opsForValue().set("associate_list", JSON.toJSONString(apAssociateWords));
            }
            if (apAssociateWords==null){
                return ResponseResult.okResult();
            }
        }
        // 4. 将词汇表封装成Trie字典树结构
        Trie trie = new Trie();
        for (ApAssociateWords apAssociateWord : apAssociateWords) {
            trie.insert(apAssociateWord.getAssociateWords()); // 将联想词加入到字典树中
        }
        // 5. 在Trie字典树查询关联的联想词   DFA算法
        List<String> associateWords = trie.getData(userSearchDto.getSearchWords());
        if(associateWords != null && !apAssociateWords.isEmpty()){
            List<ApAssociateWords> wordsList = associateWords.stream().map(s -> {
                ApAssociateWords word = new ApAssociateWords();
                word.setAssociateWords(s);
                return word;
            }).collect(Collectors.toList());
            // 6. 封装返回结果
            return ResponseResult.okResult(wordsList);
        }
        return ResponseResult.okResult();
    }
}
